在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-19
並且有測試可以讓大家練習。
今天使用 Either
來改寫 day-17-Option-usage
的範例。
type User = {
username: string;
email: string;
password: string;
};
const moreThan3Chars = (xs: string) => xs.length > 3 ? xs : throw New Error('Need more than 3 chars');
const validateEmail = (email: string) => email.includes('@') ? email : throw New Error('Invalud email');
const moreThan6Chars = (xs: string) => xs.length > 6 ? xs : throw New Error('Need more than 6 chars');
const hasCapital = (xs: string) => /[A-Z]/.test(xs) ? xs : throw New Error('Need at least one capital letter');
const hasNumber = (xs: string) => /\d/.test(xs) ? xs : throw New Error('Need at least one number');
const validateOriginal = ({ username, email, password }: User) => {
try {
moreThan3Chars(username);
validateEmail(email);
moreThan6Chars(password);
hasCapital(password);
hasNumber(password);
return { username, email, password };
} catch (error) {
return error;
}
};
這邊使用 trycatch
block 來統一所有的 execption
的處理,如果所有條件都和規則回傳使用者,否則拋出 Error
,接著使用 Either
來改寫。
const moreThan3Chars = E.fromPredicate(
(xs: string) => xs.length > 3,
() => 'Need more than 3 chars',
);
const validateEmail = E.fromPredicate(
(xs: string) => xs.includes('@'),
() => 'Invalid email',
);
const moreThan6Chars = E.fromPredicate(
(xs: string) => xs.length > 6,
() => 'Need more than 6 chars',
);
const hasCapital = E.fromPredicate(
(xs: string) => /[A-Z]/.test(xs),
() => 'Need at least one capital letter',
);
const hasNumber = E.fromPredicate(
(xs: string) => /\d/.test(xs),
() => 'Need at least one number',
);
const validate = ({ username, email, password }: User) => pipe(
username,
moreThan3Chars,
E.bindTo('username'),
E.apS('email', validateEmail(email)),
E.apS('password', pipe(
password,
moreThan6Chars,
E.chain(hasCapital),
E.chain(hasNumber),
)),
);
今天的主題在 should-i-use-fp-ts 在 src/day-19
並且有測試可以讓大家練習。